package com.example.demo.config;

import com.example.demo.security.filter.AuthFilter;
import com.example.demo.security.handler.AccessDeniedHandler;
import com.example.demo.security.handler.AuthFailureHandler;
import com.example.demo.security.handler.AuthSuccessHandler;
import com.example.demo.security.handler.LogoutSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.CorsConfigurer;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.CorsUtils;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import javax.annotation.Resource;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;


@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig{

    @Resource
    private AuthenticationConfiguration auth;



    //创建BCryptPasswordEncoder注入到容器中
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationManager authenticationManager() throws Exception{
        return auth.getAuthenticationManager();
    }

//    配置自定义用户名密码拦截器为Bean
    @Bean
    public UsernamePasswordAuthenticationFilter authFilter() throws Exception{
        UsernamePasswordAuthenticationFilter myAuthFilter = new AuthFilter();
        // 注意，因为是自定义登录拦截器，所以登录接口地址要在此配置！
        myAuthFilter.setFilterProcessesUrl("/employee/login");
        // 设定为自定义的登录成功/失败处理器
        myAuthFilter.setAuthenticationSuccessHandler(new AuthSuccessHandler());
        myAuthFilter.setAuthenticationFailureHandler(new AuthFailureHandler());
        myAuthFilter.setAuthenticationManager(auth.getAuthenticationManager());
        return myAuthFilter;
    }

    @Bean
    public SecurityFilterChain securityWebFilterChain(HttpSecurity httpSecurity) throws Exception {
//        http.cors().and().csrf().disable();
//        http.httpBasic()
//                .and()
//                .authorizeRequests()
//                //自定义放行接口
//                .antMatchers(
//                        "/swagger**/**",
//                        "/swagger-ui.html",
//                        "/swagger-resources/**",
//                        "/webjars/**",
//                        "/v3/**",
//                        "/business/login",
//                        "/business/register",
//                        "/business/updatePwd",
//                        "/index"
//                ).permitAll()
//                .anyRequest()
//                .authenticated();
//                .and().logout().logoutUrl("/logout")
//                //登出处理
//                //添加关于自定义的认证过滤器和自定义的授权过滤器
//                .and()
//                .logout().permitAll()//注销行为任意访问
//                //会话管理
//                .and().sessionManagement()
//                //同一账号同时登录最大用户数
//                .maximumSessions(1);

        //自定义权限拒绝处理类
        // 无权访问 JSON 格式的数据
//        http.exceptionHandling().accessDeniedHandler(ajaxAccessDeniedHandler);
//        // 登录验证
//        http.addFilter(new TokenLoginFilter(authenticationManager(),redisUtils,logService,powerManagerMapper,powerManagerService)).httpBasic();
//        // JWT Filter
//        http.addFilterBefore(tokenAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

        // 设定认证拦截器
        httpSecurity
                .cors().configurationSource(corsConfigurationSource())
                .and()
//                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
//                .and()

                .authorizeRequests()
                // 需要登录后才能获取用户信息
                .antMatchers("employee/login").permitAll()
                .antMatchers("/swagger**/**",
                        "/swagger-ui.html",
                        "/swagger-resources/**",
                        "/webjars/**",
                        "/v3/**",
                        "/business/login",
                        "/business/register",
                        "/business/updatePwd",
                        "/user/**",
                        "/employee/login",
                        "/employee/logout",
                        "/business/menu/**"
                ).permitAll()
                .antMatchers(HttpMethod.OPTIONS)
                .permitAll();
//                .anyRequest().authenticated();
        // 自定义退出登录url和配置自定义的登出成功处理器
        httpSecurity.logout().logoutUrl("/employee/logout").logoutSuccessHandler(new LogoutSuccessHandler());
        // 关闭csrf
        httpSecurity.csrf().disable();
        // 设定自己的登录认证拦截器
//        httpSecurity.addFilterAt(authFilter(), UsernamePasswordAuthenticationFilter.class);
        // 设定为自定义的权限不足处理器
        httpSecurity.exceptionHandling().accessDeniedHandler(new AccessDeniedHandler());
        //允许跨域
//        httpSecurity.cors();

        return httpSecurity.build();
    }

//    @Bean
//    public CorsConfigurationSource corsConfigurationSource(){
//        CorsConfiguration corsConfiguration=new CorsConfiguration();
//        corsConfiguration.setAllowedHeaders(Arrays.asList("*"));
//        corsConfiguration.setAllowedOrigins(Arrays.asList("*")); // 允许所有来源
//        corsConfiguration.setAllowedMethods(Arrays.asList("GET","POST","PUT","DELETE","OPTIONS"));
//        corsConfiguration.setAllowCredentials(true);
////        corsConfiguration.setAllowedOrigins(Arrays.asList("http://localhost:8081"));
//        corsConfiguration.setMaxAge(3600L);
//        UrlBasedCorsConfigurationSource source=new UrlBasedCorsConfigurationSource();
//        //所有的请求都允许跨域
//        source.registerCorsConfiguration("/**",corsConfiguration);
//        return  source;
//    }


    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOriginPatterns(Arrays.asList("*")); // 允许所有来源
//        configuration.setAllowedOriginPatterns(Arrays.asList("http://localhost:8081","http://172.29.15.165:8081")); // 允许所有来源
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); // 允许的HTTP方法
        configuration.setAllowedHeaders(Arrays.asList("*")); // 允许的请求头
        configuration.setAllowCredentials(true); // 允许发送cookies

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }




}
